<?php
/**
 * Created by PhpStorm.
 * User: figo-007
 * Date: 2016/11/30
 * Time: 19:32
 */
namespace ApigilityOrder\Service;

use ApigilityCatworkFoundation\Base\ApigilityEventAwareObject;
use Zend\ServiceManager\ServiceManager;
use Zend\Hydrator\ClassMethods as ClassMethodsHydrator;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator as DoctrineToolPaginator;
use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator as DoctrinePaginatorAdapter;
use ApigilityOrder\DoctrineEntity;
use ApigilityUser\DoctrineEntity\User;
use Zend\Math\Rand;
use ApigilityAddress\DoctrineEntity\Region;
use ApigilityFinance\DoctrineEntity\Ledger;

class PaymentService extends ApigilityEventAwareObject
{
    const EVENT_PAY_SUCCESS = 'PaymentService.EVENT_PAY_SUCCESS';
    const SEX_MALE = 1;
    const SEX_FEMALE = 2;

    protected $classMethodsHydrator;

    /**
     * @var \Doctrine\ORM\EntityManager
     */
    protected $em;

    /**
     * @var PaymentServiceAdapter\PaymentServiceAdapterInterface
     */
    protected $paymentAdapter;

    /**
     * @var \ApigilityOrder\Service\OrderService
     */
    protected $orderService;
    /**
     * @var \ApigilityUser\Service\UserService
     */
    protected $userService;

    /**
     * @var \ApigilityGroup\Service\SettingService
     */
    protected $settingService;

    /**
     * @var \ApigilityGroup\Service\GroupService
     */
    protected $groupService;

    /**
     * @var \ApigilityGroup\Service\ParticipationDetailService
     */
    protected $participationDetailService;

    /**
     * @var \ApigilityAddress\Service\RegionService
     */
    protected $regionService;

    /**
     * @var \ApigilityVIP\Service\ContractService
     */
    protected $contractService;

    /**
     * @var \ApigilitySocial\Service\PersonService
     */
    protected $personService;

    /**
     * @var \ApigilityFinance\Service\LedgerService
     */
    protected $ledgerService;

    public function __construct(ServiceManager $services, PaymentServiceAdapter\PaymentServiceAdapterInterface $adapter = null)
    {
        $this->classMethodsHydrator = new ClassMethodsHydrator();
        $this->em = $services->get('Doctrine\ORM\EntityManager');
        $this->orderService = $services->get('ApigilityOrder\Service\OrderService');
        $this->userService = $services->get('ApigilityUser\Service\UserService');
        $this->settingService = $services->get('ApigilityGroup\Service\SettingService');
        $this->groupService = $services->get('ApigilityGroup\Service\GroupService');
        $this->participationDetailService = $services->get('ApigilityGroup\Service\ParticipationDetailService');
        $this->regionService = $services->get('ApigilityAddress\Service\RegionService');
        $this->contractService = $services->get('ApigilityVIP\Service\ContractService');
        $this->personService = $services->get('ApigilitySocial\Service\PersonService');
        $this->ledgerService = $services->get('ApigilityFinance\Service\LedgerService');
        $this->paymentAdapter = $adapter;
    }

    public function setAdapter(PaymentServiceAdapter\PaymentServiceAdapterInterface $adapter)
    {
        $this->paymentAdapter = $adapter;
    }

    public function makeClientPaymentData($order_id)
    {
        $order = $this->orderService->getOrder($order_id);
        return $this->paymentAdapter->makePaymentData($order);
    }

    public function handlePaymentServerNotification()
    {
        $orderService = $this->orderService;
        $em = $this->em;
        $this->paymentAdapter->handleNotification(function ($order_sn, $payment_type, $payment_sn) use ($orderService, $em){
            // 如果支付成功，这里将处理订单状态
            $order = $orderService->getOrderBySN($order_sn);

            if ((int)$order->getStatus() == $order::STATUS_WAIT_TO_PAY) {
                $participationDetails = $this->participationDetailService->getParticipationDetailsByOrder($order);
                if(count($participationDetails)>0 && isset($participationDetails[0])){
                    $participationDetail = $participationDetails[0];
                    $group_id = $participationDetail->getGroup()->getId();
                    $group = $this->groupService->getGroup($group_id);
                    $group_setting = $group->getGroupSetting();

                    $u = $this->userService->getUser($order->getUser()->getId());

                    $sex = $u->getSex();

                    if($sex == $this::SEX_MALE){
                        $group->setMaleParticipationNums($group->getMaleParticipationNums() + 1);
                    } else {
                        $group->setFemaleParticipationNums($group->getFemaleParticipationNums() + 1);
                    }

                    $participationDetail->setStatus(1);
                    $order->setPaymentSeriesNumber($payment_sn);
                    $order->setPaymentType($payment_type);
                    $order->setPayTime(new \DateTime());
                    $em->flush();
                    // 处理财务记账
                    $this->ledgerService->createLedger((object)[
                        'account' => 'vip_contract_income',
                        'amount'  => $order->getTotal(),
                        'amount_type' => Ledger::AMOUNT_TYPE_DEBIT
                    ]);
                    $participation_details = $this->participationDetailService->getParticipationDetailsByGroupId($group_id);
                    if (count($participation_details) == $group_setting->getBeingGroupNums()) {
                        foreach ($participation_details as $participation_detail) {
                            $user = $this->userService->getUser($participation_detail->getUser()->getId());
                            $contract = $this->contractService->getContractByOrderId($participation_detail->getOrder()->getId());
                            $contracts = $this->contractService->getContractsByUser($user); // 获取某个用户已有的合约列表
                            $expire_time = count($contracts) ? (new \DateTime())->setTimestamp($contracts[0]->getExpireTime()->getTimestamp() + $contract->getService()->getExpire()) :
                                (new \DateTime())->setTimestamp((new \DateTime())->getTimestamp() + $contract->getService()->getExpire());
                            $participation_detail->setExpires($expire_time);
                            $contract->setEffectiveTime(count($contracts) ? $contracts[0]->getExpireTime() : $contract->getEffectiveTime());
                            $contract->setExpireTime($participation_detail->getExpires()); // 把参团时间更新到合约过期时间
                            $person = $this->personService->getPersonByUserId($participation_detail->getUser()->getId());
                            $person->setVipStatus($participation_detail->getContract()->getService()->getStatus());
                            $person->setVipExpireTime($participation_detail->getExpires());
                            $this->contractService->getContract($participation_detail->getContract()->getId())->getOrder()->setStatus(3);
                            $em->flush();

                            /*if($person->getVipExpireTime() < $expire_time && count($contracts)>0){
                                $contract->setEffectiveTime(count($contracts) ? $contracts[0]->getExpireTime() : $contract->getEffectiveTime());
                                $contract->setExpireTime($expire_time);
                                $em->flush();
                            }*/

                        }
                    }
                    /*$person = $this->personService->getPersonByUserId($u->getId());
                    $person->setVipStatus($participationDetail->getContract()->getService()->getStatus());
                    $person->setVipExpireTime($participationDetail->getExpires());*/
                }else{
                    $order->setStatus($order::STATUS_PAYED);
                    $order->setPaymentSeriesNumber($payment_sn);
                    $order->setPaymentType($payment_type);
                    $order->setPayTime(new \DateTime());


                    $u = $this->userService->getUser($order->getUser()->getId());
                    $contract = $this->contractService->getContractByOrderId($order->getId());
                    $contracts = $this->contractService->getContractsByUser($u); // 获取某个用户已有的合约列表
                    $expire_time = count($contracts) ? (new \DateTime())->setTimestamp($contracts[0]->getExpireTime()->getTimestamp() + $contract->getService()->getExpire()) :
                        (new \DateTime())->setTimestamp((new \DateTime())->getTimestamp() + $contract->getService()->getExpire());

                    $person = $this->personService->getPersonByUserId($u->getId());
                    $person->setVipStatus($contract->getService()->getStatus());
                    $person->setVipExpireTime($contract->getExpireTime());
                    $em->flush();
                    if($person->getVipExpireTime() < $expire_time && count($contracts)>0){
                        $contract->setEffectiveTime(count($contracts) ? $contracts[0]->getExpireTime() : $contract->getEffectiveTime());
                        $contract->setExpireTime($expire_time);
                        $em->flush();
                    }

                    // 处理财务记账
                    $this->ledgerService->createLedger((object)[
                        'account' => 'vip_contract_income',
                        'amount'  => $order->getTotal(),
                        'amount_type' => Ledger::AMOUNT_TYPE_DEBIT
                    ]);
                }

                /*$order->setPaymentSeriesNumber($payment_sn);
                $order->setPaymentType($payment_type);
                $order->setPayTime(new \DateTime());*/


               // $this->getEventManager()->trigger(self::EVENT_PAY_SUCCESS, $this, ['order' => $order]);
            }
        });
    }
}